<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <!-- 3.添加组件标签 注意有两种写法-->
      <!-- <todo-header @addTodo="addTodo"/>给todo-header标签对象绑定addTodo事件监听 -->
      <todo-header ref="header"/> <!--使用ref-->
      <!-- 4,.组件通信订阅消息 -->
      <todo-list :todos="todos"/>
      <!-- 1.TodoFooter组件标签给App.vue传三个参数，
      即TodoFooter里的props的声明属性
      2.第二个和第三个是函数，所以要在App.vue里写，因为数据在哪就在哪写更新数据的行为属性
       -->
      <!-- <todo-footer :todos="todos" :deleteCompleteTodos="deleteCompleteTodos" :selectAllTodos="selectAllTodos"/> -->
      <todo-footer>
        <input type="checkbox" v-model="isAllCheck" slot="checkAll"/>
        <span slot="count">已完成{{completeSize}}  / 全部{{todos.length}}</span>
        <button class="btn btn-danger" v-show="completeSize" @click="deleteCompleteTodos" slot="delete">清除已完成任务</button>
      </todo-footer>
    </div>
  </div>
</template>

<script>
//1.引入子组件
import TodoHeader from "./components/TodoHeader.vue";
import TodoList from "./components/TodoList.vue";
import TodoFooter from "./components/TodoFooter.vue";
import PubSub from 'pubsub-js'
// 引入存储模块的库（自己写的）
import storageUtil from './util/storageUtil'
export default {
  data(){
      return{
        /* todos:[
          {title:'吃饭',complete:false},
          {title:'睡觉',complete:true},
          {title:'敲代码',complete:false},
        ] */
        //从localStorage读取todos
        // JSON.parse(window.localStorage.getItem('todos_key') || '[]')
        todos:storageUtil.readTodos(),

      }
  },
  computed: {
    completeSize(){
      return this.todos.reduce((preTotal, todo) => preTotal + (todo.complete?1:0),0);
    },
    isAllCheck:{
      get(){//返回完成个数是否等于todos的长度，true、false
        return this.completeSize===this.todos.length && this.todos.length>0;
      },
      set(value){//value是当前checkbox最新的值
      this.selectAllTodos(value);
      }
    }

  },
  mounted(){//执行异步代码
      //给<todo-header/>绑定事件监听
      // this.$on('addTodo',this.addTodo) //给App绑定的监听，不对的
      this.$refs.header.$on('addTodo',this.addTodo);//利用ref找到header再绑定事件监听

      //订阅消息
      /* PubSub.subscribe('deleteTodo',function(msg,data){ }) */
     PubSub.subscribe('deleteTodo',(msg,index)=>{
       this.deleteTodo(index);//把function回调函数变成箭头函数
     })
  },

  methods:{
    // 在当前todos的前面插入todo，
    addTodo(todo){
      this.todos.unshift(todo);
    },
    //删除Todo的函数
    deleteTodo(index){
      this.todos.splice(index,1);//因为todos是数组，要删除todo就是根据todos的下标来删除，后面的参数是删除的个数
    },
    // 删除所有选中的todo，过滤
    deleteCompleteTodos(){
      // 过滤留下为false，this.todos.filter(todo => !todo.complete);
      //更新
      this.todos = this.todos.filter(todo => !todo.complete);
    },
    /*  1.全选或全不选，
        2.函数要不要传参？
        3.要传参，传形参还是实参，名字叫啥？
    */
    selectAllTodos(check){
      // 表示todos遍历todo的complete=check，check表示是否选中
      this.todos.forEach(todo =>todo.complete = check);

    }
    
  },

  watch:{//监视
    todos:{
      deep:true,//深度监视
      /* handler:function(value){
        //将todos最新的值的json，保存到localStorage
        // setItem()两个参数，第一个参数要跟getItem对应，
        取的是字符串，设置的也是字符串，但是需要数组，所以用json去解析
        // window.localStorage.setItem('todos_key',JSON.stringify(value));
        storageUtil.saveTodos(value);
      } */
      handler:storageUtil.saveTodos,//等价于上面的
    }

  },

  // 2.映射组件
  components: {
    TodoHeader,
    TodoList,
    TodoFooter,
    TodoList,
  },
};
</script>

<style>
/*app*/
.todo-container {
  width: 600px;
  margin: 0 auto;
}
.todo-container .todo-wrap {
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 5px;
}

</style>